package com.nowcoder.community.dao.impl;

import com.nowcoder.community.dao.EntityLikeDao;
import com.nowcoder.community.util.Constants;
import com.nowcoder.community.util.RedisKeyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class EntityLikeDaoRedisImpl implements EntityLikeDao {
    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    private String getEntityLikeKey(int type, int entityId) {
        String key = null;
        if (type == Constants.ENTITY_TYPE_COMMENT) {
            key = RedisKeyUtils.getCommentLikeSetKey(entityId);
        } else if (type == Constants.ENTITY_TYPE_POST) {
            key = RedisKeyUtils.getPostLikeSetKey(entityId);
        }
        return key;
    }

    private void incrUserLike(int userId) {
        redisTemplate.opsForValue().increment(RedisKeyUtils.getUserLikeCountKey(userId));
    }

    private void decrUserLike(int userId) {
        redisTemplate.opsForValue().decrement(RedisKeyUtils.getUserLikeCountKey(userId));
    }

    @Override
    public void like(int entityType, int entityId, int userId, int userIdOfEntity) {
        String key = getEntityLikeKey(entityType, entityId);
        if (key != null) {
            redisTemplate.opsForSet().add(key, userId);
            incrUserLike(userIdOfEntity);
        }
    }

    @Override
    public void unlike(int entityType, int entityId, int userId, int userIdOfEntity) {
        String key = getEntityLikeKey(entityType, entityId);
        if (key != null) {
            redisTemplate.opsForSet().remove(key, userId);
            decrUserLike(userIdOfEntity);
        }
    }

    @Override
    public int selectEntityLikeCount(int entityType, int entityId) {
        String key = getEntityLikeKey(entityType, entityId);
        Long ret;
        if (key != null && (ret = redisTemplate.opsForSet().size(key)) != null) {
            return ret.intValue();
        }
        return 0;
    }

    @Override
    public int selectUserLikeCount(int userId) {
        String key = RedisKeyUtils.getUserLikeCountKey(userId);
        Integer ret;
        if ((ret = (Integer) redisTemplate.opsForValue().get(key)) != null) {
            return ret;
        }
        return 0;
    }

    @Override
    public boolean isUserLike(int userId, int entityType, int entityId) {
        String key = getEntityLikeKey(entityType, entityId);
        if (key != null) {
            return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, userId));
        }
        return false;
    }

    @Override
    public int getLikeStatus(int userId, int entityType, int entityId) {
        if (isUserLike(userId, entityType, entityId)) {
            return Constants.LIKE_STATUS_LIKED;
        } else {
            return Constants.LIKE_STATUS_UNLIKED;
        }
    }
}
